﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;
using System.Diagnostics;
using System.Xml.Serialization;
using System.IO;

namespace intelliEssay.ApplicationExceptionReportingRecordingRedistributing
{
    public sealed class intelliEssayException : IComparable<intelliEssayException>, IComparable
    {
        static Regex fileWalker = new Regex("in (\\w:[\\\\\\w\\.]+.cs)");
        public intelliEssayException(Exception ex, int distributionID, string filepath)
        {
            this.StackTrace = ex.StackTrace;
            YearPlusMonth = (DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString());
            Status = "resources\\pending.png";
            MatchCollection mc = fileWalker.Matches(this.StackTrace);
            SourceFilePath = mc[0].Groups[1].Value;
            TestFilePath = filepath;
            DistributionID = distributionID.ToString();
            ExceptionTypeName = ex.GetType().Name;
            Message = ex.Message;
        }
        public intelliEssayException()
        {


        }
        public string SourceFilePath { get; set; }
        public string Message { get; set; }
        public string ExceptionTypeName { get; set; }
        public int LocationInLine { get; set; }
        public string Status { get; set; }
        public string TestFilePath { get; set; }
        public string DistributionID { get; set; }
        public string AssemblyVersion { get; set; }
        //   intelliEssay.Core.Task _Task;
        //string _StackTrace;
        public override bool Equals(object obj)
        {
            if (obj == this)
                return true;
            return false;
        }
        public static void FireException()
        {
            throw new ApplicationException("This is a test exception");
        }
        public void OpenSourceFiles()
        {
            MatchCollection mc = fileWalker.Matches(StackTrace);
            foreach (Match m in mc)
            {
                Process.Start(m.Groups[1].Value);
            }
        }
        public void OpenTestFile()
        {
            Process.Start(TestFilePath);
        }
        public void Distribute(string toMemberID)
        {
            BugCollection.InitializeBugCollectionIfNotPresent(DeveloperInformation.GetDeveloperNameByID(toMemberID));
            bool loadOk = BugCollection.LoadBugCollection(DeveloperInformation.GetDeveloperNameByID(toMemberID));
            if (loadOk)
            {
                BugCollection.bugCollection.Add(this);
                string testName = TestFilePath.Substring(TestFilePath.LastIndexOf("\\") + 1, TestFilePath.Length - TestFilePath.LastIndexOf("\\") - 1);
                if (File.Exists(@"x:\intelliessaybugcheck\bug check system\testFiles\" + testName))
                {
                    testName = "(NEW)" + testName;
                }
                try
                {
                    File.Copy(TestFilePath, @"x:\intelliessaybugcheck\bug check system\testFiles\" + testName);
                }
                catch
                { }
                TestFilePath = "testFiles\\" + TestFilePath.Substring(TestFilePath.LastIndexOf("\\") + 1, TestFilePath.Length - TestFilePath.LastIndexOf("\\") - 1);
                BugCollection.SaveBugCollection(DeveloperInformation.GetDeveloperNameByID(toMemberID));
            }
            else
            {
                List<intelliEssayException> temp = new List<intelliEssayException>();
                temp.Add(this);
                string testName = TestFilePath.Substring(TestFilePath.LastIndexOf("\\") + 1, TestFilePath.Length - TestFilePath.LastIndexOf("\\") - 1);

                TestFilePath = "testFiles\\" + testName;

                using (Stream stream = File.Open(@"x:\intelliessaybugcheck\bug check system\AdditionalBugFrom" + toMemberID + "To" + toMemberID + ".xml", FileMode.OpenOrCreate))
                {
                    List<intelliEssayException> additional = new List<intelliEssayException>();
                    try
                    {
                        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<intelliEssayException>));
                        additional = (List<intelliEssayException>)xmlSerializer.Deserialize(stream);
                        temp.AddRange(additional);
                    }
                    catch
                    {

                    }
                }
                using (Stream stream = File.Open(@"x:\intelliessaybugcheck\bug check system\AdditionalBugFrom" + toMemberID + "To" + toMemberID + ".xml", FileMode.OpenOrCreate))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(List<intelliEssayException>));
                    serializer.Serialize(stream, temp);
                }


                if (File.Exists(@"x:\intelliessaybugcheck\bug check system\testFiles\" + testName))
                {
                    testName = "(NEW)" + testName;
                }
                try
                {
                    File.Copy(TestFilePath, @"x:\intelliessaybugcheck\bug check system\testFiles\" + testName);
                }
                catch
                { }

            }
        }
        public void Notify(string toMemberID)
        {
            string emailAdd = DeveloperInformation.GetDeveloperEmailByID(toMemberID);
            System.Diagnostics.Process.Start("mailto:" + emailAdd + "?subject=intelliEssay Runtime Exception Notification&body=ExceptionTypeName:" + ExceptionTypeName + "%0aSourceFileLocation:" + SourceFilePath + "%0aTestFilePath:x:\\intelliessay bug check system\\testfiles\\" + TestFilePath + "%0aStackTrace:" + StackTrace + "%0aMessage" + Message);
        }
        public int CompareTo(intelliEssayException iee)
        {
            return -1;
        }
        public int CompareTo(object o)
        {
            return -1;
        }
        public string YearPlusMonth { get; set; }
        public string StackTrace
        {
            get;
            set;
        }
        //  public string LastModificationIdentifier { get; set; }
    }
    public static class BugCollection
    {
        public static void InitializeBugCollectionIfNotPresent(string username)
        {
            if (!File.Exists(@"x:\intelliessaybugcheck\bug check system\bugcollection" + username + ".xml"))
                SaveBugCollection(username);
        }
        public static List<ApplicationExceptionReportingRecordingRedistributing.intelliEssayException> bugCollection = new List<intelliEssayException>();
        public static bool LoadBugCollection(string username)
        {
            try
            {
                if (File.Exists(@"X:\intelliEssayBugCheck\Bug Check System\engage" + username))
                {
                    return false;
                }
            }
            catch
            {
                if (File.Exists(@"X:\intelliEssayBugCheck\Bug Check System\engage" + username))
                {
                    throw new InvalidOperationException("The intelliEssay Bug Check System is turned on by " + username + " - no import supported");
                }
            }
            Stream stream;
            using (stream = File.Open(@"X:\intelliEssayBugCheck\Bug Check System\BugCollection" + username + ".xml", FileMode.OpenOrCreate))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<intelliEssayException>));
                bugCollection = (List<ApplicationExceptionReportingRecordingRedistributing.intelliEssayException>)xmlSerializer.Deserialize(stream);
            }
            return true;
        }
        public static void SaveBugCollection(string username)
        {
            try
            {
                Process pro = Process.GetProcessesByName("intelliEssayBugCheckSystem").First();
                throw new InvalidOperationException("The intelliEssay Bug Check System is turned on by " + username + " - no import supported");
            }
            catch
            {
                if (File.Exists(@"X:\intelliEssayBugCheck\Bug Check System\engage" + username))
                {
                    throw new InvalidOperationException("The intelliEssay Bug Check System is turned on by " + username + " - no import supported");
                }
            }
            Stream stream;
            using (stream = File.Open(@"X:\intelliEssayBugCheck\Bug Check System\BugCollection" + username + ".xml", FileMode.OpenOrCreate))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<intelliEssayException>));
                xmlSerializer.Serialize(stream, bugCollection);
            }
        }
    }
    public class Assembly_Author_Pair
    {
        public string assemblyName;
        public string authorName;
    }
    public static class DeveloperInformation
    {
        public static string GetUserNameFromAllHints()
        {
            string LoggedName = System.Environment.UserName.Replace(" ", "").ToLowerInvariant();
            if (LoggedName.Contains("kingwolf") || LoggedName.Contains("lisnb") || LoggedName.Contains("lxp")) return "李希鹏";
            if (LoggedName.Contains("wc") || LoggedName.Contains("llmainland") ) return "罗量";
            if (LoggedName.Contains("古剑寒") || LoggedName.Contains("gjh")) return "镇明敏";
            if (LoggedName.Contains("xiaoyuan") || LoggedName.Contains("宋") || LoggedName.Contains("sxy")) return "宋小远";
            return "Unknown";

        }
        public static string[] users = new string[] { "李希鹏", "宋小远", "罗量", "镇明敏" };
        public static string[] GetAllDynamicLinkLibraries()
        {
            string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll");
            return files;
        }
        public static string GetDeveloperEmailByName(string developerName)
        {
            return GetDeveloperEmailByID(GetIDByDeveloperName(developerName));
        }
        public static string GetDeveloperEmailByID(string distributionID)
        {
            /*378168250@qq.com; 624237402@qq.com;
            songxiaoyuan.nkcs@gmail.com;
            llmainland@live.cn*/
            if (distributionID == "0") return "Unknown";
            if (distributionID == "1") return "378168250@qq.com";
            if (distributionID == "2") return "songxiaoyuan.nkcs@gmail.com";
            if (distributionID == "3") return "llmainland@live.cn";
            if (distributionID == "4") return "624237402@qq.com";
            throw new ApplicationException("No such ID exists");
        }
        public static string GetIDByDeveloperName(string developerName)
        {

            for (int i = 0; i < users.Length; i++)
            {
                if (users[i] == developerName) return (++i).ToString();
            }
            throw new ApplicationException("No Such Developer exists");
        }
        public static string GetDeveloperNameByID(string distributionID)
        {
            if (distributionID == "0") return "Unknown";
            if (distributionID == "1") return "李希鹏";
            if (distributionID == "2") return "宋小远";
            if (distributionID == "3") return "罗量";
            if (distributionID == "4") return "镇明敏";
            throw new ApplicationException("No such developer exists");
        }
        public static string GetDeveloperNameByAssemblyName(string assemblyName)
        {
            using (Stream s = File.Open(@"X:\intelliEssay.Core\Latest Release\assemblyName-authormapper.xml", FileMode.Open))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Assembly_Author_Pair[]));
                Assembly_Author_Pair[] aaps = (Assembly_Author_Pair[])xmlSerializer.Deserialize(s);
                return (from aap in aaps where aap.assemblyName.ToLowerInvariant() == assemblyName.ToLowerInvariant() select aap.authorName).First();
            }
        }
        public static void SaveDeveloperAssemblyPair(Assembly_Author_Pair[] info)
        {
            using (Stream s = File.Open(@"X:\intelliEssay.Core\Latest Release\assemblyName-authormapper.xml", FileMode.Open))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Assembly_Author_Pair[]));
                xmlSerializer.Serialize(s, info);
            }
        }
        public static Assembly_Author_Pair[] GetAllDeveloperAssemblyPair()
        {
            using (Stream s = File.Open(@"X:\intelliEssay.Core\Latest Release\assemblyName-authormapper.xml", FileMode.Open))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Assembly_Author_Pair[]));
                return xmlSerializer.Deserialize(s) as Assembly_Author_Pair[];
            }
        }
    }
}
